package cn.lili.modules.member.serviceimpl;

import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.SnowFlake;
import cn.lili.modules.member.entity.dos.RedPackInviteHelp;
import cn.lili.modules.member.entity.dos.RedPackTask;
import cn.lili.modules.member.entity.dos.RedPackUser;
import cn.lili.modules.member.entity.dos.RedPackUserTask;
import cn.lili.modules.member.mapper.RedPackTaskMapper;
import cn.lili.modules.member.mapper.RedPackUserTaskMapper;
import cn.lili.modules.member.service.*;
import cn.lili.modules.payment.entity.dto.UserRedPackUpdateDTO;
import cn.lili.modules.payment.entity.enums.UserRedPackServiceEnum;
import cn.lili.modules.promotion.entity.enums.PromotionStatusEnum;
import cn.lili.modules.statistics.entity.enums.SearchTypeEnum;
import cn.lili.modules.statistics.util.StatisticsDateUtil;
import cn.lili.modules.system.entity.dos.LiVip;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Service
@AllArgsConstructor
public class RedPackUserTaskServiceImpl extends ServiceImpl<RedPackUserTaskMapper, RedPackUserTask>
        implements RedPackUserTaskService {

    private final RedissonClient redissonClient;

    private final RedPackInviteHelpService redPackInviteHelpService;

    @Resource
    private RedPackTaskMapper redPackTaskMapper;

    private final RedPackUserService redPackUserService;

    /**
     * 获取用户当天任务
     * @param taskId
     * @return
     */
    @Override
    public RedPackUserTask getTodayUserTask (String taskId) {
        Date[] dates = StatisticsDateUtil.getDateArray(SearchTypeEnum.TODAY);
        LambdaQueryWrapper<RedPackUserTask> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RedPackUserTask::getTaskId, taskId);
        queryWrapper.eq(RedPackUserTask::getUserId, UserContext.getCurrentId());
        queryWrapper.between(RedPackUserTask::getCreateTime, dates[0], dates[1]);
        queryWrapper.orderByDesc(RedPackUserTask::getCreateTime);
        queryWrapper.last("limit 1");
        return this.getOne(queryWrapper);
    }

    /**
     * 获取用户当天任务列表
     * @param taskId
     * @return
     */
    @Override
    public long getTodayUserTaskList (String taskId) {
        Date[] dates = StatisticsDateUtil.getDateArray(SearchTypeEnum.TODAY);
        LambdaQueryWrapper<RedPackUserTask> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RedPackUserTask::getTaskId, taskId);
        queryWrapper.eq(RedPackUserTask::getStatus, 1);
        queryWrapper.eq(RedPackUserTask::getUserId, UserContext.getCurrentId());
        queryWrapper.between(RedPackUserTask::getCreateTime, dates[0], dates[1]);
        return this.count(queryWrapper);
    }


    /**
     * 开红包
     * @param id
     * @return
     */
    @Override
    public int openRedPack (String id) {
        RLock rLock = redissonClient.getLock("openRedPack_" + id);
        try {
            rLock.lock();
            RedPackUserTask redPackUserTask = this.getById(id);
            if (null == redPackUserTask) {
                throw new ServiceException("用户红包任务不存在");
            }
            if (redPackUserTask.getStatus() == 1) {
                throw new ServiceException("无法领取红包");
            }

            RedPackTask redPackTask = redPackTaskMapper.selectById(redPackUserTask.getTaskId());
            if (null == redPackTask || !PromotionStatusEnum.START.name().equals(redPackTask.getStatus())) {
                throw new ServiceException("红包任务不存在或已关闭");
            }
            int redPackCount = 0;
            if (redPackTask.getTaskType() == 1) {
                List<RedPackInviteHelp> redPackInviteHelpList = redPackInviteHelpService.getListByFlag(redPackUserTask.getTaskId());
                if (redPackInviteHelpList.isEmpty()) {
                    throw new ServiceException("当前没有红包可领取");
                }
                // 用户本次获取红包 = 任务未领取红包用户人数 * 红包任务奖励
                redPackCount = redPackInviteHelpList.size() * redPackTask.getRedPackCount();
                // 更新用户任务红包奖励和状态
                redPackUserTask.setStatus(1);
                redPackUserTask.setRedPackCount(redPackCount);
                this.updateById(redPackUserTask);
                // 更新用户红包状态未领取为已领取
                redPackInviteHelpService.updateInviteHelp(redPackInviteHelpList);
                saveUserTask(redPackTask.getId());

                redPackUserService.updateMemberRedPack(UserRedPackUpdateDTO.builder()
                        .userId(UserContext.getCurrentId())
                        .redPack(redPackCount)
                        .userRedPackServiceEnum(UserRedPackServiceEnum.INVITE_TASK)
                        .description(UserRedPackServiceEnum.INVITE_TASK.getDescription()).build());
            }else {
                redPackCount = redPackTask.getRedPackCount();
                // 更新用户任务红包奖励和状态
                redPackUserTask.setStatus(1);
                redPackUserTask.setRedPackCount(redPackCount);
                this.updateById(redPackUserTask);

                long count = getTodayUserTaskList(redPackTask.getId());
                //RedPackUser redPackUser = redPackUserService.getRedPackUser(UserContext.getCurrentId());
                // 未达到当日任务次数上限
                if (count < redPackTask.getEverydayCount() || redPackTask.getEverydayCount() == 0) {
                    saveUserTask(redPackTask.getId());
                }
                /*if (null != redPackUser && redPackUser.getIsVip() == 1) {
                    // 未达到当日会员任务次数上限
                    if (count < redPackTask.getVipCount() || redPackTask.getVipCount() == 0) {
                        saveUserTask(redPackTask.getId());
                    }
                }else {
                    // 未达到当日任务次数上限
                    if (count < redPackTask.getEverydayCount() || redPackTask.getEverydayCount() == 0) {
                        saveUserTask(redPackTask.getId());
                    }
                }*/
                redPackUserService.updateMemberRedPack(UserRedPackUpdateDTO.builder()
                        .userId(UserContext.getCurrentId())
                        .redPack(redPackCount)
                        .userRedPackServiceEnum(UserRedPackServiceEnum.ADVERT_TASK)
                        .description(UserRedPackServiceEnum.ADVERT_TASK.getDescription()).build());
            }
            return redPackCount;
        }catch (Exception e) {
            throw e;
        }finally {
            rLock.unlock();
        }
    }

    public void saveUserTask (String taskId) {
        RedPackUserTask saveRedPackUserTask = new RedPackUserTask();
        saveRedPackUserTask.setUserId(UserContext.getCurrentId());
        saveRedPackUserTask.setTaskId(taskId);
        saveRedPackUserTask.setRedPackCount(0);
        saveRedPackUserTask.setOpenId(Objects.requireNonNull(UserContext.getCurrentUser()).getOpenId());
        saveRedPackUserTask.setStatus(0);
        saveRedPackUserTask.setId(SnowFlake.getIdStr());
        this.save(saveRedPackUserTask);
    }

    /**
     * 广告任务回调
     * @param userTaskId
     */
    @Override
    public void advertCallback (String userTaskId) {
        RLock rLock = redissonClient.getLock("advertCallback_" + userTaskId);
        try {
            rLock.lock();
            RedPackUserTask redPackUserTask = this.getById(userTaskId);
            if (null == redPackUserTask) {
                throw new ServiceException("用户红包任务不存在");
            }
            if (redPackUserTask.getStatus() == 2) {
                return;
            }
            RedPackTask redPackTask = redPackTaskMapper.selectById(redPackUserTask.getTaskId());
            if (null == redPackTask || !PromotionStatusEnum.START.name().equals(redPackTask.getStatus())) {
                throw new ServiceException("红包任务不存在或已关闭");
            }
            redPackUserTask.setStatus(2);
            this.updateById(redPackUserTask);
        }catch (Exception e) {
            throw e;
        }finally {
            rLock.unlock();
        }
    }
}
